#ifndef _WX_HTMLPARS_H_
#define _WX_HTMLPARS_H_

#include "wx/defs.h"
#include "wx/html/htmltag.h"
#include "wx/filesys.h"
#include "wx/hash.h"
#include "wx/fontenc.h"

class wxMBConv;
class wxHtmlParser;
class wxHtmlTagHandler;
class wxHtmlEntitiesParser;

class wxHtmlTextPieces;
class wxHtmlParserState;


enum wxHtmlURLType {
  wxHTML_URL_PAGE,
  wxHTML_URL_IMAGE,
  wxHTML_URL_OTHER
};

class wxHtmlParser : public wxObject {
    DECLARE_ABSTRACT_CLASS( wxHtmlParser )

  public:
    wxHtmlParser();
    virtual ~wxHtmlParser();
    void SetFS( wxFileSystem *fs ) { m_FS = fs; }
    wxFileSystem* GetFS() const { return m_FS; }
    virtual wxFSFile *OpenURL( wxHtmlURLType type, const wxString& url ) const;
    wxObject* Parse( const wxString& source );
    virtual void InitParser( const wxString& source );
    virtual void DoneParser();
    virtual void StopParsing() { m_stopParsing = true; }
    void DoParsing( int begin_pos, int end_pos );
    void DoParsing();
    wxHtmlTag *GetCurrentTag() const { return m_CurTag; }
    virtual wxObject* GetProduct() = 0;
    virtual void AddTagHandler( wxHtmlTagHandler *handler );
    void PushTagHandler( wxHtmlTagHandler *handler, const wxString& tags );
    void PopTagHandler();
    wxString* GetSource() {return &m_Source;}
    void SetSource( const wxString& src );
    virtual void SetSourceAndSaveState( const wxString& src );
    virtual bool RestoreState();
    wxString GetInnerSource( const wxHtmlTag& tag );
    static wxString ExtractCharsetInformation( const wxString& markup );
    wxHtmlEntitiesParser *GetEntitiesParser() const { return m_entitiesParser; }
  protected:
    void CreateDOMTree();
    void DestroyDOMTree();
    void CreateDOMSubTree( wxHtmlTag *cur,int begin_pos, int end_pos,wxHtmlTagsCache *cache );
    virtual void AddText( const wxChar* txt ) = 0;
    virtual void AddTag( const wxHtmlTag& tag );
  protected:
    wxHtmlTag *m_CurTag;
    wxHtmlTag *m_Tags;
    wxHtmlTextPieces *m_TextPieces;
    size_t m_CurTextPiece;
    wxString m_Source;
    wxHtmlParserState *m_SavedStates;
    wxList m_HandlersList;
    wxHashTable m_HandlersHash;
    DECLARE_NO_COPY_CLASS( wxHtmlParser )
    wxFileSystem *m_FS;
    wxList *m_HandlersStack;
    wxHtmlEntitiesParser *m_entitiesParser;
    bool m_stopParsing;
};

class wxHtmlTagHandler : public wxObject {
    DECLARE_ABSTRACT_CLASS( wxHtmlTagHandler )
  public:
    wxHtmlTagHandler() : wxObject() { m_Parser = NULL; }
    virtual void SetParser( wxHtmlParser *parser ) { m_Parser = parser; }
    virtual wxString GetSupportedTags() = 0;
    virtual bool HandleTag( const wxHtmlTag& tag ) = 0;

  protected:
    void ParseInner( const wxHtmlTag& tag ) { m_Parser->DoParsing( tag.GetBeginPos(), tag.GetEndPos1() ); }
    void ParseInnerSource( const wxString& source );
    wxHtmlParser *m_Parser;
    DECLARE_NO_COPY_CLASS( wxHtmlTagHandler )
};

class wxHtmlEntitiesParser : public wxObject {
    DECLARE_DYNAMIC_CLASS( wxHtmlEntitiesParser )
  public:
    wxHtmlEntitiesParser();
    virtual ~wxHtmlEntitiesParser();
    void SetEncoding( wxFontEncoding encoding );
    wxString Parse( const wxString& input );
    wxChar GetEntityChar( const wxString& entity );
    wxChar GetCharForCode( unsigned code ) { return ( wxChar )code; }
  protected:
    DECLARE_NO_COPY_CLASS( wxHtmlEntitiesParser )
};

#endif
